package com.linln.admin.message.controller;

import com.github.binarywang.wxpay.bean.request.WxPayRefundRequest;
import com.github.binarywang.wxpay.bean.result.WxPayRefundResult;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.binarywang.wxpay.service.WxPayService;
import com.linln.admin.message.validator.MessageInfoValid;
import com.linln.common.constant.AdminConst;
import com.linln.common.constant.NoticeTypeConst;
import com.linln.common.constant.UrlConst;
import com.linln.common.enums.StatusEnum;
import com.linln.common.utils.*;
import com.linln.common.vo.ResultVo;
import com.linln.modules.member.domain.MemberAgent;
import com.linln.modules.member.domain.MemberOrder;
import com.linln.modules.member.domain.MemberRefund;
import com.linln.modules.member.service.MemberAgentService;
import com.linln.modules.member.service.MemberOrderService;
import com.linln.modules.member.service.MemberRefundService;
import com.linln.modules.message.domain.MessageInfo;
import com.linln.modules.message.domain.MessageRefund;
import com.linln.modules.message.domain.MessageType;
import com.linln.modules.message.repository.MessageInfoRepository;
import com.linln.modules.message.repository.MessageRefundRepository;
import com.linln.modules.message.service.MessageInfoService;
import com.linln.modules.message.service.MessageMemberLogService;
import com.linln.modules.message.service.MessageTypeService;
import com.linln.modules.system.domain.Area;
import com.linln.modules.system.service.AreaService;

import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.ExampleMatcher;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @author hct
 * @date 2019/09/12
 */
@Controller
@RequestMapping("/message/messageInfo")
public class MessageInfoController {
    private static final String REFUND_SUCCESS = "SUCCESS";
    private static final String REFUND_FAIL = "FAIL";

    @Autowired
    private MessageInfoService messageInfoService;
    @Autowired
    private AreaService areaService;
    @Autowired
    private MessageTypeService typeService;
    @Autowired
    private MessageInfoRepository messageInfoRepository;
    @Autowired
    private MemberAgentService agentService;

    @Autowired
    private WxPayService wxPayService;
    @Autowired
    private MemberRefundService refundService;
    @Autowired
    private MessageMemberLogService messageMemberLogServiceImpl;
    @Autowired
    private MessageRefundRepository messageRefundRepository;

    @Autowired
    private MemberOrderService orderService;
    /**
     * 列表页面
     */
    @GetMapping("/index")
    @RequiresPermissions("message:messageInfo:index")
    public String index(Model model, MessageInfo messageInfo,Long message_type2) {

    	ExampleMatcher matchertype = ExampleMatcher.matching();
        // 获取部门列表
    	MessageType type=new MessageType();
        Example<MessageType> exampleType = Example.of(type, matchertype);
        Sort sort = new Sort(Sort.Direction.ASC, "num");
        List<MessageType> typealllist = typeService.getListByExample(exampleType, sort);
		List<MessageType> typelist=new ArrayList<MessageType>();
        for(MessageType messageType:typealllist) {
        	if(messageType.getPid()!=null && messageType.getPid().longValue()>0) {
        		typelist.add(messageType);
        	}
        }
        // 创建匹配器，进行动态查询匹配
        ExampleMatcher matcher = ExampleMatcher.matching();
        matcher.withMatcher("title", match -> match.contains());
        if(message_type2!=null && message_type2.longValue()>0) {
        	MessageType typenew=new MessageType();
        	typenew.setId(message_type2);
        	messageInfo.setTypetwo(typenew); 
        }
        // 获取数据列表
        messageInfo.setMessageStatus(1);
        Example<MessageInfo> example = Example.of(messageInfo, matcher);
        Page<MessageInfo> list = messageInfoService.getPageList(example);
        List<MessageInfo> listinfo=list.getContent();
        for (MessageInfo messageInfo_ :listinfo
        ) {
            if(messageInfo_==null) continue;
            Area area = areaService.findByCode(messageInfo_.getArea());
            if(area != null){
                Area parea = areaService.getById(area.getPid());
                messageInfo_.setAreaname(area.getName());
                if(parea != null){
                    messageInfo_.setAreaname(parea.getName()+area.getName());
                }
            }
        }
        // 封装数据
        model.addAttribute("typelist", typelist);
        model.addAttribute("message_type2", message_type2);
        model.addAttribute("list", listinfo);
        model.addAttribute("page", list);
        return "/message/messageInfo/index";
    }

    /**
     * 跳转到添加页面
     */
    @GetMapping("/add")
    @RequiresPermissions("message:messageInfo:add")
    public String toAdd() {
        return "/message/messageInfo/add";
    }

    /**
     * 跳转到编辑页面
     */
    @GetMapping("/edit/{id}")
    @RequiresPermissions("message:messageInfo:edit")
    public String toEdit(@PathVariable("id") MessageInfo messageInfo, Model model) {
        model.addAttribute("messageInfo", messageInfo);
        return "/message/messageInfo/add";
    }

    /**
     * 保存添加/修改的数据
     * @param valid 验证对象
     */
    @PostMapping("/save")
    @RequiresPermissions({"message:messageInfo:add", "message:messageInfo:edit"})
    @ResponseBody
    public ResultVo save(@Validated MessageInfoValid valid, MessageInfo messageInfo) {
        // 复制保留无需修改的数据
        if (messageInfo.getId() != null) {
            MessageInfo beMessageInfo = messageInfoService.getById(messageInfo.getId());
            EntityBeanUtil.copyProperties(beMessageInfo, messageInfo);
        }

        // 保存数据
        messageInfoService.save(messageInfo);
        return ResultVoUtil.SAVE_SUCCESS;
    }

    /**
     * 跳转到详细页面
     */
    @GetMapping("/detail/{id}")
    @RequiresPermissions("message:messageInfo:detail")
    public String toDetail(@PathVariable("id") MessageInfo messageInfo, Model model) {
        	Area area=areaService.findByCode(messageInfo.getArea());
        	if(area!=null) {
        		messageInfo.setAreaname(area.getName());
        	}
        
        model.addAttribute("messageInfo",messageInfo);
        return "/message/messageInfo/detail";
    }

    /**
     * 跳转到详细页面
     */
    @GetMapping("/selectEdit/{id}")
    @RequiresPermissions("message:messageInfo:selectEdit")
    public String selectEdit(@PathVariable("id") MessageInfo messageInfo, Model model) {
        Area area=areaService.findByCode(messageInfo.getArea());
        if(area!=null) {
            messageInfo.setAreaname(area.getName());
        }

        model.addAttribute("messageInfo",messageInfo);
        return "/message/messageInfo/edit";
    }

    /**
     * 编辑
     */
    @PostMapping("/editMessageInfo")
    @ResponseBody
    public ResultVo editMessageInfo(Long id, String details, String title, String logo, String nineImgs, String startTime, HttpServletRequest request){
        Integer integerdetails = messageInfoRepository.updateMessageInfodetails(id, details);
        Integer integertitle = messageInfoRepository.updateMessageInfotitle(id, title);
        messageInfoRepository.updateMessageInfoImgs(id,nineImgs);
        messageInfoRepository.updateMessageInfoLogo(id,logo);
        messageInfoRepository.updateMessageInfoStartTime(id, DateUtils.strToDate(startTime,"yyyy-MM-dd hh:mm:ss"));
        System.out.println(id+"----"+details);
        ResultVo success = ResultVoUtil.success("修改成功");
        return success;
    }
    /**
     * 设置一条或者多条数据的状态
     */
    @RequestMapping("/status/{param}")
    @RequiresPermissions("message:messageInfo:status")
    @ResponseBody
    public ResultVo status(
            @PathVariable("param") String param,
            @RequestParam(value = "ids", required = false) List<Long> ids) {
        // 更新状态
        StatusEnum statusEnum = StatusUtil.getStatusEnum(param);
        if (messageInfoService.updateStatus(statusEnum, ids)) {
            return ResultVoUtil.success(statusEnum.getMessage() + "成功");
        } else {
            return ResultVoUtil.error(statusEnum.getMessage() + "失败，请重新操作");
        }
    }

    @RequestMapping("/refundRedirect/{id}")
    public String refundRedirect(@PathVariable("id") MessageInfo baseinfo,Model model){
        model.addAttribute("messageInfo",baseinfo);
        return "/message/messageInfo/refund";
    }


    /**
     * 下架消息 并将钱退回去
     * @param model
     * @param id
     *    0待审核 1同意 2拒绝
     * @param request
     * @return
     */
    @RequestMapping("/refundMessage")
    @ResponseBody
    public ResultVo refundMessage(Model model, Long id,String refundContent,HttpServletRequest request) {
        MessageInfo message=messageInfoService.getById(id);
        //MemberInfo agent=(MemberInfo)request.getSession().getAttribute(AdminConst.AGENT_ROLE_NAME);
        if(messageInfoService.updateMessageStatus(2, id)) {
            MessageRefund messageRefund=new MessageRefund();
            messageRefund.setMessageId(id);
            messageRefund.setMemberId(message.getMember().getId());
            messageRefund.setCreateDate(new Date());
            messageRefund.setUpdateDate(new Date());
            messageRefund.setContent(refundContent);
            messageRefund.setStatus(0);
            messageRefundRepository.save(messageRefund);
            MemberOrder memberOrder=orderService.findByOrderCode(message.getOrderId());
            if(message.getIstop()==1 && memberOrder.getMoney().doubleValue()>0) {//置顶的退款 其他的拒绝掉
                //拒绝的时候将费用退回给客户 申请退款
                WxPayRefundRequest refundInfo = WxPayRefundRequest.newBuilder()
                        //订单号
                        .outTradeNo(message.getOrderId())
                        //退款订单号
                        .outRefundNo(ToolUtil.getRandomString(16))
                        //金额
                        .totalFee(yuanToFee(new BigDecimal(memberOrder.getMoney())))
                        //退款金额
                        .refundFee(yuanToFee(new BigDecimal(memberOrder.getMoney())))

                        //todo 回调地址
                        .notifyUrl(UrlConst.REFUNDNOTICEURL)
                        .build();
                WxPayRefundResult wxPayRefundResult;
                try {
                    wxPayRefundResult = wxPayService.refund(refundInfo);
                    //判断退款信息是否正确
                    if (REFUND_SUCCESS.equals(wxPayRefundResult.getReturnCode())
                            && REFUND_SUCCESS.equals(wxPayRefundResult.getResultCode())) {
                        if(StringUtils.isNoneBlank(message.getArea())) {
                            MemberAgent agentnew = agentService.getByArea(message.getArea());
                            if(agentnew!=null) {
                                agentnew.setAllmoney(MoneyUtils.sub(agentnew.getAllmoney(), message.getFee()));
                                agentnew.setCurmoney(MoneyUtils.sub(agentnew.getCurmoney(), message.getFee()));
                                agentService.save(agentnew);
                                saveRefund(message,memberOrder, agentnew.getId());
                            }
                        }

                        orderService.updateRefundStatus(message.getOrderId());
                    }else if(REFUND_FAIL.equals(wxPayRefundResult.getReturnCode())){
                        return ResultVoUtil.success("下架成功,但退款失败:"+wxPayRefundResult.getReturnMsg());
                    }
                } catch (WxPayException e) {
                    System.out.println("没有需要退款的情况=="+e.getReturnMsg());
                }
                return ResultVoUtil.success("下架成功");

            }else {
                //大后台操作
                saveRefund( message,memberOrder,0L);
            }



            return ResultVoUtil.success("下架成功");

        }else {
            return ResultVoUtil.error("下架失败");
        }

    }


    public void saveRefund(MessageInfo message,MemberOrder order,Long agentId) {
        MemberRefund refund=new MemberRefund();
        refund.setAgentId(agentId);
        refund.setArea(message.getArea());
        refund.setMoney(0d);
        refund.setRefundmoney(0d);

        refund.setContent("下架普通信息");
        if(message.getIstop().intValue()==1) {
            refund.setContent("拒绝用户置顶信息");
            refund.setMoney(order.getMoney());
            refund.setRefundmoney(order.getMoney());
        }
        refund.setOrderCode(message.getOrderId());
        refund.setRefundStatus(0);
        refund.setType(NoticeTypeConst.MESSAGE);
        refund.setTypeId(message.getId());
        refundService.save(refund);
    }

    /**
     * 1 块钱转为 100 分
     * 元转分
     *
     * @param bigDecimal 钱数目
     * @return 分
     */
    private int yuanToFee(BigDecimal bigDecimal) {
        return bigDecimal.multiply(new BigDecimal(100)).intValue();
    }

    /**
     * 时间
     *
     * @return 时间戳
     */
    private String createTimestamp() {
        return Long.toString(System.currentTimeMillis() / 1000);
    }
}